#pragma once 

/* 聊天会话表的ODB映射 */

#include <string>
#include <cstddef> // std::size_t
#include <odb/nullable.hxx>
#include <odb/core.hxx>
#include "chat_session_member.hxx"

namespace ChatSystem
{
    enum class ChatSessionType
    {
        SINGLE = 1,     //单聊
        GROUP = 2       //群聊
    };  

    #pragma db object table("chat_session")
    //聊天会话表映射的对象
    class ChatSession
    {
    public:
        ChatSession(){}
        ~ChatSession(){}

        ChatSession(const std::string& chat_session_id, const std::string& chat_session_name, const ChatSessionType chat_session_type)
        :_chat_session_id(chat_session_id), _chat_session_name(chat_session_name), _chat_session_type(chat_session_type)
        {}

        //获取聊天会话ID
        std::string chat_session_id() const
        {
            return _chat_session_id;
        }
        //获取聊天会话ID
        std::string chat_session_id()
        {
            return _chat_session_id;
        }
        //修改聊天会话ID
        void chat_session_id(const std::string& val)
        {
            _chat_session_id = val;
        }

        //获取聊天会话名称
        std::string chat_session_name() const
        {
            return _chat_session_name;
        }
        //获取聊天会话名称
        std::string chat_session_name()
        {
            return _chat_session_name;
        }
        //修改聊天会话名称
        void chat_session_name(const std::string& val)
        {
            _chat_session_name = val;
        }

        //获取聊天会话类型
        ChatSessionType chat_session_type() const
        {
            return _chat_session_type;
        }
        //获取聊天会话类型
        ChatSessionType chat_session_type()
        {
            return _chat_session_type;
        }
        //修改聊天会话类型
        void chat_session_type(const ChatSessionType val)
        {
            _chat_session_type = val;
        }

    private:
        friend class odb::access;   //建立友元关系，以便odb框架来访问我们的私有成员
        
        #pragma db id auto
        unsigned long _id;  //主键---这个只能保证同一主机上的用户之间不能重复，而不能保证不同主机数据库上id的唯一性

        #pragma db type("varchar(64)") index unique
        std::string _chat_session_id;   //聊天会话ID---不能重复，所以是唯一索引
        #pragma db type("varchar(64)") 
        std::string _chat_session_name;   //聊天会话名称
        #pragma db type("tinyint")
        ChatSessionType _chat_session_type;     //聊天会话类型：1-单聊  2-群聊
    };


    //创建视图，用于多表联合查询 --- chat_session 表和 chat_session_member 表联合查询指定用户单聊的所有好友
    //这里的过滤条件必须是指定条件： css::chat_session_type==1 && csm1::user_id==uid && csm2::user_id != csm1::user_id
    #pragma db view object(ChatSession = css)\
                    object(ChatSessionMember = csm1 : css::_chat_session_id == csm1::_chat_session_id)\
                    object(ChatSessionMember = csm2 : css::_chat_session_id == csm2::_chat_session_id)\
                    query((?))
    struct SingleChatSession
    {
        #pragma db column(css::_chat_session_id)
        std::string chat_session_id;
        #pragma db column(csm2::_user_id)
        std::string friend_id;
    };

    //创建视图，用于多表联合查询 --- chat_session 表和 chat_session_member 表联合查询指定用户的所有群聊会话
    //这里的过滤条件必须是指定条件： css::chat_session_type==2 && csm::user_id == uid
    //这里给数据表定义了别名，就必须在过滤条件中使用表的别名，而不能使用原来的表名了；否则会报原来的表未定义的错误；
    #pragma db view object(ChatSession = css)\
                    object(ChatSessionMember = csm : css::_chat_session_id == csm::_chat_session_id)\
                    query((?))
    struct GroupChatSession
    {
        #pragma db column(css::_chat_session_id)
        std::string chat_session_id;
        #pragma db column(css::_chat_session_name)
        std::string chat_session_name;
    };

    //这个不需要了，与联合查询指定用户单聊的所有好友的过滤条件不一样而已
    // //创建视图，用于多表联合查询 --- chat_session 表和 chat_session_member 表联合查询指定好友关系的单聊聊天会话ID
    // //这里的过滤条件必须是指定条件： csm1::user_id == user_id && csm2::user_id == peer_id && css::chat_session_type == 1
    // //这里给数据表定义了别名，就必须在过滤条件中使用表的别名，而不能使用原来的表名了；否则会报原来的表未定义的错误；
    // #pragma db view object(ChatSession = css)\
    //                 object(ChatSessionMember = csm1 : css::_chat_session_id == csm1::_chat_session_id)\
    //                 object(ChatSessionMember = csm2 : css::_chat_session_id == csm2::_chat_session_id)\
    //                 query((?))
    // struct SingleChatSessionID 
    // {
    //     #pragma db column(css::_chat_session_id)
    //     std::string chat_session_id;
    // };
}

//odb 编译：odb -d mysql --generate-query --generate-schema --profile boost/date-time chat_session.hxx